﻿using System;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace BuildServer.Models
{
    public enum BuildState
    {
        None = 0,
        Scheduled = 1,
        Started = 2,
        Finished = 3
    }

    public enum BuildRunAge
    {
        /// <summary>
        /// Build less than a day ago
        /// </summary>
        LastDay = 1,
        
        /// <summary>
        /// Build less then a week ago
        /// </summary>
        LastWeek = 2,

        /// <summary>
        /// Older than a week
        /// </summary>
        Older = 3,
    }

    public static class BuildRunAgeConverter
    {
        public static string ToString(BuildRunAge age)
        {
            switch(age)
            {
                case BuildRunAge.LastDay:
                    return "Last day";
                case BuildRunAge.LastWeek:
                    return "Last week";
                case BuildRunAge.Older:
                    return "Older";
                default:
                    return "Unknown";
            }
        }
    }

    public class BuildRun
    {
        [Key]
        public int Id { get; set; }

        [Display(Name = "Scheduled")]
        public DateTime? Scheduled { get; set; }

        [Display(Name = "Started")]
        public DateTime? Start { get; set; }

        [Display(Name = "Finished")]
        public DateTime? End { get; set; }

        [Required(ErrorMessage = "Build Target is required")]
        public string Targets { get; set; }

        [Required(ErrorMessage = "Build Definition is required")]
        [Column("BuildDefinition_Id")]
        public int BuildDefinitionId { get; set; }

        [Display(Name = "Build Log")]
        public string BuildLog { get; set; }

        [Display(Name = "Compile Log")]
        public string CompileLog { get; set; }

        [Display(Name = "Build Definition")]
        [ForeignKey("BuildDefinitionId")]
        public virtual BuildDefinition BuildDefinition { get; set; }

        [NotMapped]
        [Display(Name = "State")]
        public BuildState State
        {
            get
            {
                if (End.HasValue)
                    return BuildState.Finished;
                else if (Start.HasValue)
                    return BuildState.Started;
                else if (Scheduled.HasValue)
                    return BuildState.Scheduled;
                else
                    return BuildState.None;
            }
        }

        [NotMapped]
        [Display(Name = "Age")]
        public BuildRunAge Age
        {
            get
            {
                DateTime? max = (new[] { Scheduled, Start, End }).Max();
                if (!max.HasValue)
                    return BuildRunAge.Older;
                TimeSpan diff = DateTime.Now.Date - max.Value;
                if (diff <= new TimeSpan(1, 0, 0, 0))
                    return BuildRunAge.LastDay;
                else if (diff <= new TimeSpan(7, 0, 0, 0))
                    return BuildRunAge.LastWeek;
                else
                    return BuildRunAge.Older;
            }
        }

        /// <summary>
        /// Schedules this build run to be run
        /// </summary>
        public void DoSchedule()
        {
            this.Scheduled = DateTime.Now;
            this.Start = null;
            this.End = null;
        }

        /// <summary>
        /// Sets the Start time and clears Scheduled and End time
        /// </summary>
        public void DoStart()
        {
            // update start and end 
            this.Start = DateTime.Now;
            this.End = null;
            // clean logs
            this.CompileLog = null;
            this.BuildLog = null;
        }
    }
}